# © 2016 Elico Corp (www.elico-corp.com).
# © 2019 信莱德软件 (www.zhsunlight.cn).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import time
import os
import base64
import logging
_logger = logging.getLogger(__name__)

from odoo import fields, models, api
from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import UserError


class IrActionsReportXml(models.Model):
    _inherit = 'ir.actions.report'

    report_type = fields.Selection(selection_add=[('docx', 'Docx'), ('xlsx', 'Xlsx')])
    template_path = fields.Char('模板路径', readonly=True)
    template_file = fields.Binary(string='模板文件')
    template_filename = fields.Char("模板文件名")
    output_type = fields.Selection(
        [
            ('pdf', 'PDF'),
            ('docx', 'Docx'),
            ('xlsx', 'Xlsx'),
        ],
        '输出类型', required=True, default='docx'
    )

    @api.constrains("template_filename")
    def constrain_template_filename(self):
        for record in self:
            exi = self.search([
                ("template_filename", "=", record.template_filename),
                ("id", "!=", record.id),
            ])
            if exi:
                raise UserError(f"已经存在{record.template_filename}的模板文件了，请检查或更换名字")

    @api.model
    def get_from_report_name(self, report_name, report_type):
        return self.search(
            [("report_name", "=", report_name),
             ("report_type", "=", report_type)])

    def render_docx(self, res_ids, data):
        self.ensure_one()
        if self.report_type != "docx":
            raise RuntimeError(
                "docx rendition is only available on docx report.\n"
                "(current: '{}', expected 'docx'".format(self.report_type))

        docx = self.env['gooderp.report.docx'].create({
            'ir_actions_report_id': self.id
        })

        return docx.create_report(res_ids, data)

    def render_xlsx(self, res_ids, data):
        self.ensure_one()
        if self.report_type != "xlsx":
            raise RuntimeError(
                "xlsx rendition is only available on xlsx report.\n"
                "(current: '{}', expected 'xlsx'".format(self.report_type))

        docx = self.env['gooderp.report.xlsx'].create({
            'ir_actions_report_id': self.id
        })

        return docx.create_report(res_ids, data)

    def gen_report_download_filename(self, res_ids, data):
        """Override this function to change the name of the downloaded report
        """
        self.ensure_one()
        report = self.get_from_report_name(self.report_name, self.report_type)
        if report.print_report_name and not len(res_ids) > 1:
            obj = self.env[self.model].browse(res_ids)
            return safe_eval(report.print_report_name,
                             {'object': obj, 'time': time})
        return "%s.%s" % (self.name, self.output_type)

    def action_store_document_dir(self):
        for record in self:
            if record.template_file:
                document_file = record.template_file
                file_location_root = "/home/odoo/templates"
                file_full_path = os.path.join(file_location_root, record.template_filename)
                try:
                    with open(file_full_path, 'wb') as f:
                        f.write(base64.b64decode(document_file))
                    record.template_path = file_full_path
                except IOError as e:
                    _logger.error(f"保存文件{file_full_path}失败：{e}")
            # else:
            #     raise UserError('没有找到文档.')
            
    @api.model
    def create(self, vals_list):
        res = super(IrActionsReportXml, self).create(vals_list)
        res.action_store_document_dir()
        return res

    def write(self, vals):
        res = super(IrActionsReportXml, self).write(vals)
        if vals.get("template_file") or vals.get("template_filename"):
            self.action_store_document_dir()
        return res

    def unlink(self):
        for record in self:
            if record.template_path:
                try:
                    os.remove(record.template_path)
                except:
                    _logger.info(f"没有找到文件{record.template_path}")
        return super(IrActionsReportXml, self).unlink()
